package io.cici.cc.mybatis.plus.extension.toolkit;


import io.cici.cc.mybatis.lite.session.Session;
import io.cici.cc.mybatis.lite.session.SqlSessionFactory;
import io.cici.cc.mybatis.plus.core.assist.ISqlRunner;
import io.cici.cc.mybatis.plus.core.toolkit.CollectionUtils;
import io.cici.cc.mybatis.plus.core.toolkit.GlobalConfigUtils;
import io.cici.cc.mybatis.plus.core.toolkit.StringUtils;
import lombok.extern.slf4j.Slf4j;

import java.util.List;
import java.util.Map;
import java.util.Optional;

@Slf4j
public class SqlRunner implements ISqlRunner {

    // 单例Query
    public static final SqlRunner DEFAULT = new SqlRunner();

    private Class<?> clazz;

    public SqlRunner() {
    }

    public SqlRunner(Class<?> clazz) {
        this.clazz = clazz;
    }

    /**
     * 获取默认的SqlQuery(适用于单库)
     *
     * @return ignore
     */
    public static SqlRunner db() {
        return DEFAULT;
    }

    /**
     * 根据当前class对象获取SqlQuery(适用于多库)
     *
     * @param clazz ignore
     * @return ignore
     */
    public static SqlRunner db(Class<?> clazz) {
        return new SqlRunner(clazz);
    }

    // @Transactional
    @Override
    public boolean insert(String sql, Object... args) {
        Session session = sqlSession();
        try {
            return SqlHelper.retBool(session.insert(INSERT, sqlMap(sql, args)));
        } finally {
            closeSqlSession(session);
        }
    }

    // @Transactional
    @Override
    public boolean delete(String sql, Object... args) {
        Session session = sqlSession();
        try {
            return SqlHelper.retBool(session.delete(DELETE, sqlMap(sql, args)));
        } finally {
            closeSqlSession(session);
        }
    }

    /**
     * 获取sqlMap参数
     *
     * @param sql  指定参数的格式: {0}, {1}
     * @param args 仅支持String
     * @return ignore
     */
    private Map<String, String> sqlMap(String sql, Object... args) {
        Map<String, String> sqlMap = CollectionUtils.newHashMapWithExpectedSize(1);
        sqlMap.put(SQL, StringUtils.sqlArgsFill(sql, args));
        return sqlMap;
    }

    // @Transactional
    @Override
    public boolean update(String sql, Object... args) {
        Session session = sqlSession();
        try {
            return SqlHelper.retBool(session.update(UPDATE, sqlMap(sql, args)));
        } finally {
            closeSqlSession(session);
        }
    }

    /**
     * 根据sql查询Map结果集
     * <p>
     * SqlRunner.db().selectList("select * from tbl_user where name={0}",
     * "Caratacus")
     * </p>
     *
     * @param sql  sql语句，可添加参数，格式：{0},{1}
     * @param args 只接受String格式
     * @return ignore
     */
    @Override
    public List<Map<String, Object>> selectList(String sql, Object... args) {
        Session session = sqlSession();
        try {
            return session.selectList(SELECT_LIST, sqlMap(sql, args));
        } finally {
            closeSqlSession(session);
        }
    }

    /**
     * 根据sql查询一个字段值的结果集
     * <p>
     * 注意：该方法只会返回一个字段的值， 如果需要多字段，请参考{@code selectList()}
     * </p>
     *
     * @param sql  sql语句，可添加参数，格式：{0},{1}
     * @param args 只接受String格式
     * @return ignore
     */
    @Override
    public List<Object> selectObjs(String sql, Object... args) {
        Session session = sqlSession();
        try {
            return session.selectList(SELECT_OBJS, sqlMap(sql, args));
        } finally {
            closeSqlSession(session);
        }
    }

    /**
     * 根据sql查询一个字段值的一条结果
     * <p>
     * 注意：该方法只会返回一个字段的值， 如果需要多字段，请参考{@code selectOne()}
     * </p>
     *
     * @param sql  sql语句，可添加参数，格式：{0},{1}
     * @param args 只接受String格式
     * @return ignore
     */
    @Override
    public Object selectObj(String sql, Object... args) {
        return SqlHelper.getObject(selectObjs(sql, args));
    }

    @Override
    public long selectCount(String sql, Object... args) {
        Session session = sqlSession();
        try {
            return SqlHelper.retCount(session.<Long>selectOne(COUNT, sqlMap(sql, args)));
        } finally {
            closeSqlSession(session);
        }
    }

    @Override
    public Map<String, Object> selectOne(String sql, Object... args) {
        return SqlHelper.getObject(selectList(sql, args));
    }

    /**
     * 获取Session 默认自动提交
     */
    private Session sqlSession() {
        // return SqlSessionUtils.getSqlSession(getSqlSessionFactory());
        return null;
    }

    /**
     * 释放sqlSession
     *
     * @param session session
     */
    private void closeSqlSession(Session session) {
        // SqlSessionUtils.closeSqlSession(sqlSession, getSqlSessionFactory());
    }

    /**
     * 获取SqlSessionFactory
     */
    private SqlSessionFactory getSqlSessionFactory() {
        return Optional.ofNullable(clazz).map(GlobalConfigUtils::currentSessionFactory).orElse(SqlHelper.FACTORY);
    }

    /**
     * @deprecated 3.5.3.2
     */
    @Deprecated
    public void close() {

    }

}
